package com.bfly.mall.order.controller;

import com.bfly.common.ResponseUtil;
import com.bfly.common.page.Pager;
import com.bfly.common.util.DataConvertUtils;
import com.bfly.common.util.DateUtil;
import com.bfly.core.base.controller.BaseController;
import com.bfly.core.base.entity.ResponseData;
import com.bfly.core.context.CacheableThreadLocal;
import com.bfly.core.context.PagerThreadLocal;
import com.bfly.core.enums.AccessRole;
import com.bfly.core.security.ActionModel;
import com.bfly.mall.admin.entity.Admin;
import com.bfly.mall.admin.service.IAdminService;
import com.bfly.mall.order.dto.*;
import com.bfly.mall.order.entity.*;
import com.bfly.mall.order.enums.ExpressStatusEnum;
import com.bfly.mall.order.enums.OrderStatusEnum;
import com.bfly.mall.order.enums.PayStatusEnum;
import com.bfly.mall.order.service.IOrderExpressService;
import com.bfly.mall.order.service.IOrderService;
import com.bfly.mall.user.entity.User;
import com.bfly.mall.user.dto.UserNameDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * 订单Controller
 *
 * @author 长沙商脉科技有限公司
 * @date 2020/4/19 9:23
 */
@RestController
@RequestMapping(value = "/manage/order")
public class OrderController extends BaseController {

    @Autowired
    private IOrderService orderService;
    @Autowired
    private IOrderExpressService expressService;

    /**
     * 订单列表
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/4/19 9:48
     */
    @GetMapping(value = "/list")
    public void listOrder(HttpServletRequest request, HttpServletResponse response) {
        PagerThreadLocal.set(request);
        Map<String, Object> param = new HashMap<>();
        String statusStr = request.getParameter("status");
        int status = DataConvertUtils.convertToInteger(statusStr);
        switch (status) {
            case 1:
                // 待发货
                param.put("order_status", OrderStatusEnum.OPEN.getId());
                param.put("pay_status", PayStatusEnum.SUCCESS.getId());
                param.put("express_status", ExpressStatusEnum.WAIT_SHIP.getId());
                break;
            case 2:
                // 待退款
                param.put("order_status_in", Arrays.asList(OrderStatusEnum.OPEN.getId(), OrderStatusEnum.COMPLETE.getId()));
                param.put("pay_status", PayStatusEnum.WAIT_REFUND.getId());
                param.put("express_status_in", Arrays.asList(ExpressStatusEnum.WAIT_SHIP.getId(), ExpressStatusEnum.SHIPPING.getId(), ExpressStatusEnum.RECEIVED.getId(), ExpressStatusEnum.RETURN_WAIT_RECEIVE.getId(), ExpressStatusEnum.RETURN_RECEIVED.getId()));
                break;
            case 3:
                // 待收货
                param.put("order_status", OrderStatusEnum.OPEN.getId());
                param.put("pay_status", PayStatusEnum.SUCCESS.getId());
                param.put("express_status", ExpressStatusEnum.SHIPPING.getId());
                break;
            case 4:
                // 未支付
                param.put("order_status", OrderStatusEnum.OPEN.getId());
                param.put("pay_status", PayStatusEnum.WAIT_PAY.getId());
                param.put("express_status", ExpressStatusEnum.INITIAL.getId());
                break;
            case 5:
                // 已取消
                param.put("order_status", OrderStatusEnum.CANCEL.getId());
                param.put("pay_status", PayStatusEnum.WAIT_PAY.getId());
                param.put("express_status", ExpressStatusEnum.INITIAL.getId());
                break;
            case 6:
                // 已完成
                param.put("order_status", OrderStatusEnum.COMPLETE.getId());
                param.put("pay_status", PayStatusEnum.SUCCESS.getId());
                param.put("express_status", ExpressStatusEnum.RECEIVED.getId());
                break;
            case 7:
                // 已关闭
                param.put("order_status", OrderStatusEnum.CLOSE.getId());
                break;
            default:
                // 全部
        }

        String orderNo = request.getParameter("orderNo");
        if (StringUtils.isNotBlank(orderNo)) {
            param.put("order_no", orderNo);
        }
        String begin = request.getParameter("beginTime");
        String end = request.getParameter("endTime");
        if (StringUtils.isNotBlank(begin) && StringUtils.isNotBlank(end)) {
            Date beginDate = DateUtil.getDayMorning(DateUtil.parseStrDate(begin));
            Date endDate = DateUtil.getDayNight(DateUtil.parseStrDate(end));

            param.put("create_date_beginDate", beginDate);
            param.put("create_date_endDate", endDate);
        }
        CacheableThreadLocal.set(false);
        Pager<Order> pager = orderService.getPage(param);
        Pager<OrderListDTO> dtoPager = new Pager<>(pager.getPageNo(), pager.getPageSize(), pager.getTotalCount());
        if (pager.getData() != null) {
            List<OrderListDTO> list = new ArrayList<>();
            OrderAddress address;
            for (Order order : pager.getData()) {
                address = order.getAddress();
                List<OrderSku> skus = order.getSkus();
                OrderListDTO dto = new OrderListDTO();

                dto.setOrderNo(order.getOrderNo());
                dto.setOrderStatus(order.getOrderStatus());
                dto.setPayStatus(order.getPayStatus());
                dto.setExpressStatus(order.getExpressStatus());
                dto.setDispatchId(order.getDispatchId());
                dto.setActivityType(order.getActivityType());
                dto.setCreateDate(order.getCreateDate());
                dto.setPayPrice(order.getPayPrice());

                if(address!=null) {
                    dto.setConsignee(address.getConsignee());
                    dto.setPhone(address.getPhone());
                    dto.setAddress(String.format("%s - %s %s %s %s", address.getPostCode(), address.getProvince(), address.getCity(), address.getDistrict(), address.getAddress()));
                }

                List<OrderSkuListDTO> skuListDTOS = new ArrayList<>();
                skus.forEach(sku -> {
                    OrderSkuListDTO skuListDTO = new OrderSkuListDTO();
                    BeanUtils.copyProperties(sku, skuListDTO);
                    skuListDTOS.add(skuListDTO);
                });

                dto.setSkus(skuListDTOS);
                list.add(dto);
            }
            dtoPager.setData(list);
        }
        ResponseUtil.writeJson(response, ResponseData.getSuccess(dtoPager));
    }

    /**
     * 订单详情
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/4/19 9:51
     */
    @GetMapping(value = "/detail")
    public void detailOrder(@RequestParam(value = "orderNo", defaultValue = "") String orderNo, HttpServletResponse response) {
        Order order = orderService.getOrder(orderNo);

        OrderDTO dto = new OrderDTO();
        if (order != null) {
            dto.setOrderNo(orderNo);
            dto.setTradeNo(order.getTradeNo());
            dto.setProductPrice(order.getProductPrice());
            dto.setPayPrice(order.getPayPrice());
            dto.setDiscountPrice(order.getDiscountPrice());
            dto.setExpressPrice(order.getExpressPrice());
            dto.setOrderStatus(order.getOrderStatus());
            dto.setPayStatus(order.getPayStatus());
            dto.setExpressStatus(order.getExpressStatus());
            dto.setPayType(order.getPayType());
            dto.setDispatchId(order.getDispatchId());
            dto.setActivityType(order.getActivityType());
            dto.setRemark(order.getRemark());

            List<OrderSku> skus = order.getSkus();
            List<OrderSkuListDTO> skuListDTOS = new ArrayList<>();
            skus.forEach(sku -> {
                OrderSkuListDTO skuListDTO = new OrderSkuListDTO();
                BeanUtils.copyProperties(sku, skuListDTO);
                skuListDTOS.add(skuListDTO);
            });
            dto.setSkus(skuListDTOS);

            dto.setLogs(order.getLogs());

            OrderAddress address = order.getAddress();
            if(address!=null) {
                OrderAddressDTO addressDTO = new OrderAddressDTO();
                addressDTO.setPhone(address.getPhone());
                addressDTO.setConsignee(address.getConsignee());
                addressDTO.setAddress(String.format("%s - %s %s %s %s", address.getPostCode(), address.getProvince(), address.getCity(), address.getDistrict(), address.getAddress()));
                dto.setAddress(addressDTO);
            }

            List<OrderExpress> expresses = order.getExpress();
            List<OrderExpressDTO> expressDTOS = new ArrayList<>();
            expresses.forEach(express -> {
                OrderExpressDTO expressDTO = new OrderExpressDTO();
                BeanUtils.copyProperties(express, expressDTO);
                expressDTOS.add(expressDTO);
            });
            dto.setExpress(expressDTOS);

            User user = order.getUser();
            UserNameDTO nameDTO = new UserNameDTO();
            BeanUtils.copyProperties(user, nameDTO);
            dto.setUser(nameDTO);
        }

        ResponseUtil.writeJson(response, ResponseData.getSuccess(dto));
    }

    /**
     * 取消订单
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/4/25 13:17
     */
    @GetMapping(value = "/cancel")
    @ActionModel(value = "取消订单")
    public void cancelOrder(@RequestParam("orderNo") String orderNo, @RequestParam("reason") String reason, HttpServletResponse response) {
        Admin admin = getAdmin();
        orderService.cancelOrder(orderNo, reason, admin.getId(), admin.getUserName(), AccessRole.MANAGER);
        ResponseUtil.writeJson(response, ResponseData.getSuccess(""));
    }

    /**
     * 订单发货
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/4/25 14:18
     */
    @PostMapping(value = "/ship")
    @ActionModel(value = "订单发货")
    public void shipOrder(@RequestBody OrderExpressFormDTO formDTO, HttpServletResponse response) {
        expressService.shopKeeperShipOrder(getAdmin(),formDTO);
        ResponseUtil.writeJson(response, ResponseData.getSuccess(""));
    }

    /**
     * 门店确认收货操作
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/4/25 19:59
     */
    @GetMapping(value = "/confirm/receive")
    @ActionModel(value = "商家确认收货")
    public void confirmReceiveShopKeeper(@RequestParam("orderNo") String orderNo, HttpServletResponse response) {
        orderService.shopKeeperConfirmReceiveForRefund(getAdmin(),orderNo);
        ResponseUtil.writeJson(response, ResponseData.getSuccess(""));
    }
}
